﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace Kokomo.Mirror.CliMetadata.Signatures
{
	class GenericTypeParamTypeSpec : GenericParamTypeSpec
	{
		public override Type ResolveType(
			Module module,
			bool throwOnError,
			Type[] genericTypeArgs,
			Type[] genericMethodArgs
			)
		{
			Type t =
				(this.index < genericTypeArgs.Length)
				? genericTypeArgs[this.index]
				: null
				;
			if (((object)t == null) && throwOnError)
				throw new TypeLoadException();

			return t;
		}
		public override string ToString()
		{
			return "!" + this.index;
		}
		public override bool Equals(object obj)
		{
			GenericTypeParamTypeSpec other = obj as GenericTypeParamTypeSpec;
			if (other == null) return false;

			bool equals =
				(this.index == other.index)
				;
			return equals;
		}
		public override bool Matches(
			Type type,
			Module module,
			Type[] genericTypeArguments,
			Type[] genericMethodArguments
			)
		{
			if ((object)type == null) throw new ArgumentNullException("type");

			Type argType = genericTypeArguments[this.index];

			bool matches =
				MemberEqualityComparer.Equal(argType, type)
				|| (
				type.IsGenericParameter
				&& ((object)type.DeclaringType != null)
				&& (type.GenericParameterPosition == this.index)
				)
				;
			return matches;
		}
		public override bool Matches(
			Module ownerModule,
			TypeSpec other,
			Module otherModule
			)
		{
			if ((object)ownerModule == null) throw new ArgumentNullException("ownerModule");
			if (other == null) throw new ArgumentNullException("other");
			if ((object)otherModule == null) throw new ArgumentNullException("otherModule");

			GenericTypeParamTypeSpec otherGeneric = other as GenericTypeParamTypeSpec;
			if (otherGeneric == null) return false;

			bool matches =
				this.index == otherGeneric.index
				;
			return matches;
		}
	}
}
